home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-07-28 | 19.6 KB | 744 lines | [TEXT/MPS ] |
- /*
- File: BTreeTupleDatabase.cp
-
- Copyright: © 1991-1994 by Apple Computer, Inc.
- All rights reserved.
-
- Part of the AOCE Sample SMSAM Package. Consult the license
- which came with this software for your specific legal rights.
-
- */
-
-
-
- #ifndef __BTREETUPLEDATABASE__
- #include "BTreeTupleDatabase.h"
- #endif
-
- #ifndef __DEBUGASSERT__
- #include "DebugAssert.h"
- #endif
-
- #ifndef __DEBUGGINGGEAR__
- #include "DebuggingGear.h"
- #endif
-
- #ifndef __BUFFER__
- #include "Buffer.h"
- #endif
-
- #ifndef __DATAITEM__
- #include "DataItem.h"
- #endif
-
- #ifndef __DEBUGCONSTANTS__
- #include "DebugConstants.h"
- #endif
-
- #ifndef __STDLIB_
- #include "StdLib.h"
- #endif
-
- /***********************************|****************************************/
-
- #pragma segment BtreeDatabase
-
- /***********************************|****************************************/
-
- class TDebugFlag;
- extern TDebugFlag chrisFlag;
-
- /***********************************|****************************************/
-
- const BTreeCompareProc
- AKeyDescriptor::GetCompareProc () const
- {
- return nil;
- }
-
- /***********************************|****************************************/
-
- ostream&
- AKeyDescriptor::operator >> ( ostream& stream ) const
- {
- stream << "AKeyDescriptor @ " << (void*) this << '\n';
- stream << "\tGetMaxKeyLength (): " << GetMaxKeyLength () << '\n';
- stream << "\tGetCompareProc (): " << (void*) GetCompareProc () << '\n';
- PrintDescriptor ( stream, GetBtreeDescriptor () );
- return stream;
- }
-
- /***********************************|****************************************/
-
- void
- AKeyDescriptor::PrintDescriptor ( ostream& stream, const unsigned char* desc ) const
- {
- const unsigned char* stop = desc + *desc;
- stream << "\tlength: " << (short) *desc++ << " bytes";
-
- while ( desc < stop )
- {
- switch ( *desc++ )
- {
- case kdSkip:
- stream << ", kdSkip";
- goto dumplen;
-
- case kdByte:
- stream << ", kdByte";
- goto dumplen;
-
- case kdWord:
- stream << ", kdWord";
- goto dumplen;
-
- case kdLong:
- stream << ", kdLong";
- goto dumplen;
-
- case kdSignedByte:
- stream << ", kdSignedByte";
- goto dumplen;
-
- case kdSignedWord:
- stream << ", kdSignedWord";
- goto dumplen;
-
- case kdSignedLong:
- stream << ", kdSignedLong";
- goto dumplen;
-
- case kdString:
- stream << ", kdString, (" << (short) *desc++ << ')';
- goto dumpcase;
-
- case kdFLString:
- stream << ", kdFLString, (" << (short) *desc++ << ')';
- goto dumpcase;
-
- case kdDTString:
- stream << ", kdDTString\n";
- break;
-
- case kdUseKCProc:
- stream << ", kdUseKCProc\n";
- break;
-
- dumplen: stream << " (" << (short) *desc++ << ')';
- break;
-
- dumpcase: if ( *desc & caseSens )
- stream << ", case sensitive:";
- else
- stream << ", case insensitive:";
-
- if ( *desc & diacNsens )
- stream << "diacrit insensitive";
- else
- stream << "diacrit sensitive";
- desc++;
- break;
-
- default:
- stream << ", ???";
- break;
- }
- }
- }
-
- /***********************************|****************************************/
-
- class CStringDescriptor : public AKeyDescriptor
- {
- public: CStringDescriptor ( Boolean caseSensitive = true, Boolean diacritSensitive = false );
- virtual ~CStringDescriptor ();
- virtual const unsigned char* GetBtreeDescriptor () const;
-
- private: unsigned char fCaseFlag, fDiacritFlag;
- };
-
- /***********************************|****************************************/
-
- class CProcedureDescriptor : public AKeyDescriptor
- {
- public:
- CProcedureDescriptor ();
- virtual ~CProcedureDescriptor ();
- virtual const unsigned char* GetBtreeDescriptor () const;
- virtual const BTreeCompareProc GetCompareProc () const;
-
- private:
- static short CompareProc ();
- };
-
- /***********************************|****************************************/
-
- class TBTreeKeyWrapper : public CPrefixDataItem
- {
- public: TBTreeKeyWrapper ( const ATupleKey& );
- virtual ~TBTreeKeyWrapper ();
- };
-
- /***********************************|****************************************/
-
- class TBTreeDataWrapper : public CPrefixDataItem
- {
- public: TBTreeDataWrapper ( ADataItem&, Boolean updateSource );
- TBTreeDataWrapper ( ADataItem&, unsigned long initialSize );
- virtual ~TBTreeDataWrapper ();
- };
-
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- inline
- TBTreeKeyWrapper::~TBTreeKeyWrapper ()
- {
- }
-
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- inline
- TBTreeDataWrapper::~TBTreeDataWrapper ()
- {
- }
-
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- inline OSErr
- TBTreeDatabase::GetError () const
- {
- return fError;
- }
-
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- CStringDescriptor::CStringDescriptor ( Boolean paramCaseSensitive, Boolean paramDiacritSensitive ):
- AKeyDescriptor (),
- fCaseFlag ( paramCaseSensitive ? caseSens : 0 ),
- fDiacritFlag ( paramDiacritSensitive ? 0 : diacNsens )
- {
- }
-
- CStringDescriptor::~CStringDescriptor ()
- {
- }
-
- const unsigned char*
- CStringDescriptor::GetBtreeDescriptor () const
- {
- static unsigned char kDescriptor [ 4 ] = { 3, kdString, 1, 0 };
- // kDescriptor [ 3 ] = fCaseFlag | fDiacritFlag;
- return kDescriptor;
- }
-
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- CProcedureDescriptor::CProcedureDescriptor ():
- AKeyDescriptor ()
- {
- }
-
- CProcedureDescriptor::~CProcedureDescriptor ()
- {
- }
-
- const unsigned char*
- CProcedureDescriptor::GetBtreeDescriptor () const
- {
- static const unsigned char kDescriptor [] = { 2, kdUseKCProc };
- return kDescriptor;
- }
-
- const BTreeCompareProc
- CProcedureDescriptor::GetCompareProc () const
- {
- return CompareProc;
- }
-
- const void* GetA1() = { 0x2009 };
- const void* GetA0() = { 0x2008 };
-
- short
- CProcedureDescriptor::CompareProc ()
- {
- NOT_IMPLEMENTED ();
- return 0;
- }
-
- /***********************************|****************************************/
-
- static const CProcedureDescriptor kProcedureDescriptor;
- const AKeyDescriptor& AKeyDescriptor::kCompareProc = kProcedureDescriptor;
-
- static const CStringDescriptor kStringDescriptor;
- const AKeyDescriptor& AKeyDescriptor::kString = kStringDescriptor;
-
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- TBTreeKeyWrapper::TBTreeKeyWrapper ( const ATupleKey& key ):
- CPrefixDataItem ( key.GetData (), key.GetLength (), CPrefixDataItem::kByte )
- {
- }
-
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- TBTreeDataWrapper::TBTreeDataWrapper ( ADataItem& buffer, Boolean update ):
- CPrefixDataItem ( buffer, update, CPrefixDataItem::kWord )
- {
- }
-
- /***********************************|****************************************/
-
- TBTreeDataWrapper::TBTreeDataWrapper ( ADataItem& buffer, unsigned long logicalLength ):
- CPrefixDataItem ( CPrefixDataItem::kWord, logicalLength )
- {
- CPrefixDataItem::SetSource ( &buffer );
- CPrefixDataItem::SetUpdate ( true );
- }
-
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- TBTreeDatabase::TBTreeDatabase ( const TFileSpec& spec, const AKeyDescriptor& descriptor, Mode mode, Rights rights ):
- ATupleDatabase (),
- fFile ( spec ),
- fError ( noErr ),
- fRights ( rights )
- {
- ::memset ( &fParam, 0, sizeof ( fParam ) );
-
- if ( mode == kReadWriteNew )
- {
- ASSERT_RETURN ( fFile.CreateFile ( 'MPS ', 'b*tr' ) );
-
- BTParam tParam;
- tParam.ioCompletion = nil;
- tParam.ioNamePtr = fFile.GetPName ();
- tParam.ioVRefNum = fFile.GetVolume ();
- tParam.ioDirID = fFile.GetParent ();
- tParam.ioBTClumpSize = 0;
- tParam.ioBTMaxKLen = (short) descriptor.GetMaxKeyLength ();
- tParam.ioBTKDPtr = (Ptr) descriptor.GetBtreeDescriptor ();
-
- ASSERT_RETURN ( HandleError ( BTInit ( &tParam, false ) ) );
- }
-
- fParam.ioVRefNum = fFile.GetVolume ();
- fParam.ioDirID = fFile.GetParent ();
- fParam.ioNamePtr = fFile.GetPName ();
- fParam.ioPermssn = mode == kReadOnly ? fsRdPerm : fsRdWrPerm;
- fParam.ioBTKCProc = (Ptr) descriptor.GetCompareProc ();
- fParam.ioBTRsrvUID = (long) this;
-
- ASSERT_RETURN ( HandleError ( BTOpen ( &fParam, false ) ) );
-
- if ( fRights == kExclusive )
- if ( ReserveAccess () == false )
- {
- fRights = kNonExclusive;
- fParam.ioBTRsrvUID = 0;
- }
- }
-
- /***********************************|****************************************/
-
- TBTreeDatabase::~TBTreeDatabase ( void )
- {
- if ( fParam.ioRefNum != 0 )
- {
- if ( fRights == kExclusive )
- ReleaseAccess ();
-
- ASSERT ( HandleError ( BTClose ( &fParam, false ) ) );
- fParam.ioRefNum = 0;
- }
- }
-
- /***********************************|****************************************/
-
- Boolean
- TBTreeDatabase::SetTuple ( const ATupleKey& key, const ADataItem& data )
- {
- TBTreeKeyWrapper keyWrapper ( key );
- TBTreeDataWrapper dataWrapper ( (ADataItem&) data, false );
- unsigned long dataLength = dataWrapper.GetPhysicalLength ();
-
- fParam.ioBTKeyPtr = (Ptr) keyWrapper.GetPhysicalStart ();
- fParam.ioBuffer = (Ptr) dataWrapper.GetPhysicalStart ();
- fParam.ioReqCount = dataLength;
-
- ASSERT_RETURN_ZERO ( HandleError ( BTSetRec ( &fParam, false ) ) );
- ASSERT_RETURN_ZERO ( dataLength == fParam.ioActCount );
-
- return true;
- }
-
- /***********************************|****************************************/
-
- Boolean
- TBTreeDatabase::SetTuple ( unsigned long index, const ADataItem& data )
- {
- ATupleKey* key = CreateKey ( index );
- ASSERT_RETURN_ZERO ( key != nil );
- Boolean result = ASSERT ( SetTuple ( *key, data ) );
- delete key;
- return result;
- }
-
- /***********************************|****************************************/
-
- Boolean
- TBTreeDatabase::GetTupleData ( unsigned long index, ADataItem& data )
- {
- ATupleKey* key = CreateKey ( index );
-
- if ( key == nil )
- return false;
-
- Boolean result = GetTupleData ( *key, data );
-
- delete key;
- return result;
- }
-
- /***********************************|****************************************/
-
- Boolean
- TBTreeDatabase::GetTupleData ( const ATupleKey& key, ADataItem& data )
- {
- TBTreeKeyWrapper keyWrapper ( key );
-
- unsigned long newDataSize = GetTupleDataSize ( keyWrapper );
-
- if ( newDataSize == 0 )
- return false;
-
- TBTreeDataWrapper dataWrapper ( data, newDataSize );
-
- fParam.ioBTKeyPtr = (Ptr) keyWrapper.GetPhysicalStart ();
- fParam.ioBuffer = (Ptr) dataWrapper.GetPhysicalStart ();
- fParam.ioReqCount = dataWrapper.GetPhysicalLength ();
-
- return HandleError ( BTSearch ( &fParam, false ) );
- }
-
- /***********************************|****************************************/
-
- Boolean
- TBTreeDatabase::GetTuple ( unsigned long index, ATupleKey& key, ADataItem& data )
- {
- if ( !GetTupleKey ( index, key ) )
- return false;
- return GetTupleData ( key, data );
- }
-
- /***********************************|****************************************/
-
- Boolean
- TBTreeDatabase::DoesTupleExist ( const ATupleKey& key ) const
- {
- unsigned long length = 0;
- return ((TBTreeDatabase*) this )->GetTupleDataSize ( key, length ) == true;
- }
-
- /***********************************|****************************************/
-
- Boolean
- TBTreeDatabase::GetTupleKey ( unsigned long index, ATupleKey& key )
- {
- CTupleKey* newKey = CreateKey ( index );
-
- if ( newKey )
- {
- key = *newKey;
- delete newKey;
- return true;
- }
- else
- return false;
- }
-
- /***********************************|****************************************/
-
- CTupleKey*
- TBTreeDatabase::CreateKey ( unsigned long index )
- {
- const unsigned long kKeyLength = MaxKeyLen;
- unsigned char keyBuffer [ kKeyLength + 1 ];
- fParam.ioBTKeyPtr = (Ptr) keyBuffer;
- fParam.ioKReqCount = (short) kKeyLength;
-
- short bufferLength = 0;
- fParam.ioBuffer = (Ptr) &bufferLength;
- fParam.ioReqCount = sizeof ( bufferLength );
- fParam.ioBTPosMode = (short) index - 1;
- InvalidateHint ();
-
- if ( !HandleError ( BTGetRec ( &fParam, false ) ) )
- return nil;
-
- #if debug
- ASSERT_RETURN_ZERO ( fParam.ioKActCount == keyBuffer [ 0 ] + 1 );
- #endif
-
- return new CTupleKey ( keyBuffer + 1, keyBuffer [ 0 ] );
- }
-
- /***********************************|****************************************/
-
- Boolean
- TBTreeDatabase::GetTupleDataSize ( const ATupleKey& key, unsigned long& dataLength )
- {
- dataLength = GetTupleDataSize ( TBTreeKeyWrapper ( key ) );
- return dataLength > 0;
- }
-
- /***********************************|****************************************/
-
- unsigned long
- TBTreeDatabase::GetTupleDataSize ( const TBTreeKeyWrapper& key )
- {
- short datADataItem = 0;
- fParam.ioBuffer = (Ptr) &datADataItem;
- fParam.ioReqCount = sizeof ( datADataItem );
- fParam.ioBTKeyPtr = (Ptr) key.GetPhysicalStart ();
- return HandleError ( BTSearch ( &fParam, false ) ) ? datADataItem : 0;
- }
-
- /***********************************|****************************************/
-
- Boolean
- TBTreeDatabase::FindIndexOfTuple ( const ATupleKey& key, unsigned long& index ) const
- {
- TBTreeKeyWrapper keyWrapper ( key );
- ((TBTreeDatabase*) this)->fParam.ioBTKeyPtr = (Ptr) keyWrapper.GetPhysicalStart ();
- ((TBTreeDatabase*) this)->fParam.ioBuffer = nil;
- ((TBTreeDatabase*) this)->fParam.ioReqCount = 0;
- ((TBTreeDatabase*) this)->fParam.ioKReqCount = 1;
- ((TBTreeDatabase*) this)->fParam.ioBTPosMode = 0;
- ((TBTreeDatabase*) this)->InvalidateHint ();
-
- if ( !HandleError ( BTSearch ( &((TBTreeDatabase*)this)->fParam, false ) ) )
- return false;
-
- index = (unsigned long) fParam.ioBTHint3 + 1;
- return true;
- }
-
- /***********************************|****************************************/
-
- Boolean
- TBTreeDatabase::DeleteTuple ( const ATupleKey& key )
- {
- TBTreeKeyWrapper keyWrapper ( key );
- fParam.ioBTKeyPtr = (Ptr) keyWrapper.GetPhysicalStart ();
-
- if ( !HandleError ( BTDelete ( &fParam, false ) ) )
- return false;
-
- return true;
- }
-
- /***********************************|****************************************/
-
- unsigned long
- TBTreeDatabase::CountTuples () const
- {
- BTParam tParam;
- return GetInfo ( tParam ) ? tParam.ioBTRecNum : 0;
- }
-
- /***********************************|****************************************/
-
- Boolean
- TBTreeDatabase::GetInfo ( BTParam& tParam ) const
- {
- tParam.ioCompletion = nil;
- tParam.ioRefNum = fParam.ioRefNum;
- tParam.ioBTKDPtr = nil;
- tParam.ioBTKDReqCount = 0;
- return HandleError ( BTGetInfo ( &tParam, false ) );
- }
-
- /***********************************|****************************************/
-
- void
- TBTreeDatabase::InvalidateHint ()
- {
- fParam.ioBTHint1 = 0;
- fParam.ioBTHint2 = 0;
- fParam.ioBTHint3 = 0;
- }
-
- /***********************************|****************************************/
-
- void
- TBTreeDatabase::Flush ()
- {
- fParam.ioBTWriteFlag = true;
- ASSERT ( HandleError ( BTFlush ( &fParam, false ) ) );
- }
-
- /***********************************|****************************************/
-
- extern ostream& DumpHex (ostream& s, const void *p, unsigned long size);
-
- void
- Print ( ostream& stream, const BTIOParam& fParam )
- {
- stream << "\tioBuffer: ";
- if ( fParam.ioBuffer )
- DumpHex ( stream, (char*) fParam.ioBuffer, fParam.ioReqCount );
- else
- stream << "<NIL>\n";
- stream << "\tioCompletion: " << fParam.ioCompletion << '\n';
- stream << "\tioResult: " << fParam.ioResult << '\n';
- stream << "\tioNamePtr:" << (StringPtr) fParam.ioNamePtr << '\n';
- stream << "\tioVRefNum: " << fParam.ioVRefNum << '\n';
- stream << "\tioRefNum: " << fParam.ioRefNum << '\n';
- stream << "\tioBTWriteFlag: " << hexo << fParam.ioBTWriteFlag << dec << '\n';
- stream << "\tioPermssn: " << (short) fParam.ioPermssn << '\n';
- stream << "\tioMisc: " << (void*) fParam.ioMisc << '\n';
- stream << "\tioReqCount: " << fParam.ioReqCount << '\n';
- stream << "\tioActCount: " << fParam.ioActCount << '\n';
- stream << "\tioBTKeyPtr: ";
- if ( fParam.ioBTKeyPtr )
- DumpHex ( stream, (char*) fParam.ioBTKeyPtr, fParam.ioBTKeyPtr [ 0 ] + 1 );
- else
- stream << "<NIL>\n";
- stream << "\tioDirID: " << fParam.ioDirID << '\n';
- stream << "\tioBTHint1: " << fParam.ioBTHint1 << '\n';
- stream << "\tioBTHint2: " << fParam.ioBTHint2 << '\n';
- stream << "\tioBTHint3: " << fParam.ioBTHint3 << '\n';
- stream << "\tioBTHint4: " << fParam.ioBTHint4 << '\n';
- stream << "\tioBTHint5: " << fParam.ioBTHint5 << '\n';
- stream << "\tioBTPosMode: " << fParam.ioBTPosMode << '\n';
- stream << "\tioKReqCount: " << fParam.ioKReqCount << '\n';
- stream << "\tioKActCount: " << fParam.ioKActCount << '\n';
- stream << "\tioBTRsrvUID: " << fParam.ioBTRsrvUID << '\n';
- stream << "\tioBTDataSize: " << fParam.ioBTDataSize << '\n';
- stream << "\tioBTKCProc: " << (void*) fParam.ioBTKCProc << '\n';
- stream.flush ();
- }
-
- /***********************************|****************************************/
-
- ostream&
- TBTreeDatabase::operator >> ( ostream& stream ) const
- {
- Boolean flag = chrisFlag.Flag ( kExtensiveTupleDBDescribe );
- Boolean flag2 = chrisFlag.Flag ( kBTreeErrorDescribe );
- chrisFlag.SetFlag ( kExtensiveTupleDBDescribe, false );
- chrisFlag.SetFlag ( kBTreeErrorDescribe, false );
-
- ATupleDatabase::operator >> ( stream );
- stream << "TBTreeDatabase @ " << (void*) this << '\n';
-
- if ( flag )
- {
- stream << fFile << endl;
- stream << "\tfError: \"" << GetErrorName ( fParam.ioResult ) << "\"\n";
- Print ( stream, fParam );
- }
-
- chrisFlag.SetFlag ( kExtensiveTupleDBDescribe, flag );
- chrisFlag.SetFlag ( kBTreeErrorDescribe, flag2 );
-
- return stream;
- }
-
- /***********************************|****************************************/
-
- Boolean
- TBTreeDatabase::HandleError ( OSErr error ) const
- {
- ( (TBTreeDatabase*) this )->fError = error;
- // ( (TBTreeDatabase*) this )->fParam.ioResult = error;
-
- #if debug
- if ( ( fError != noErr ) && chrisFlag.Flag ( kBTreeErrorDescribe ) )
- {
- Boolean prevFlag = chrisFlag.Flag ( kExtensiveTupleDBDescribe );
- chrisFlag.SetFlag ( kExtensiveTupleDBDescribe, true );
- chris << "\n\n######### ERROR ########\n" << *this << '\n';
- chrisFlag.SetFlag ( kExtensiveTupleDBDescribe, prevFlag );
- }
- #endif
-
- return fError == noErr;
- }
-
- /***********************************|****************************************/
-
- Boolean
- TBTreeDatabase::DeleteDatabase ()
- {
- if ( fParam.ioRefNum != 0 )
- {
- ASSERT_RETURN_ZERO ( HandleError ( BTClose ( &fParam, false ) ) );
- fParam.ioRefNum = 0;
- }
-
- ASSERT_RETURN_ZERO ( fFile.DeleteFile () );
- return true;
- }
-
- /***********************************|****************************************/
-
- Boolean
- TBTreeDatabase::ReserveAccess ()
- {
- ASSERT_RETURN_ZERO ( HandleError ( BTRsrvAccess ( &fParam, false ) ) );
- return true;
- }
-
- /***********************************|****************************************/
-
- Boolean
- TBTreeDatabase::ReleaseAccess ()
- {
- ASSERT_RETURN_ZERO ( HandleError ( BTRelAccess ( &fParam, false ) ) );
- return true;
- }
-
- /***********************************|****************************************/
-
- extern const char* GetErrorName ( OSErr );
-
- const char*
- TBTreeDatabase::GetErrorName ( OSErr error )
- {
- switch ( error )
- {
- case notBTree: return "notBTree";
- case btBadNode: return "btBadNode";
- case btSizeErr: return "btSizeErr";
- case btNoSpace: return "btNoSpace";
- case btDupRecErr: return "btDupRecErr";
- case btRecNotFnd: return "btRecNotFnd";
- case btKeyLenErr: return "btKeyLenErr";
- case btKeyAttrErr: return "btKeyAttrErr";
- case btKeyFdErr: return "btKeyFdErr";
- case btPMInvalid: return "btPMInvalid";
- case btKDLenErr: return "btKDLenErr";
- case btKDTypeErr: return "btKDTypeErr";
- case btBadUIDErr: return "btBadUIDErr";
- case btNoKDErr: return "btNoKDErr";
- case btDepthErr: return "btDepthErr";
- case btNoKCProcErr: return "btNoKCProcErr";
- case btVersionErr: return "btVersionErr";
- case btEofErr: return "btEofErr";
- case btBofErr: return "btBofErr";
- default: return ::GetErrorName ( error );
- }
- }
-
- /***********************************|****************************************/
-